package org.example.socket;

import lombok.extern.slf4j.Slf4j;
import org.example.http.ChatHttpSender;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;


@Component
//服务器端点
@ServerEndpoint("/chatWebSocket/{uid}")
@Slf4j
public class ChatSocketServer {
    //定义了一个请求发送器
    private static ChatHttpSender httpSender;

    //用map把websocket客户端存储七年，客户端集合，key是uid
    private static ConcurrentHashMap<String, ChatSocketServer> socketClients = new ConcurrentHashMap<>();

    //会话对象，通过他来向客户端发请求
    private Session session;

    //接收uid，代表客户端用户
    private String uid = "";

    //注入sender
    @Resource
    public void setHttpSender(ChatHttpSender httpSender){
        this.httpSender = httpSender;
    }

    /**
     * 建立连接
     * @param session 会话
     * @param uid 连接用户名称
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("uid") String uid) {
        this.session = session;
        this.uid = uid;
        socketClients.put(uid, this);
        log.info("客户端{} , 建立连接",uid);
    }

    @OnClose
    public void onClose() {
        socketClients.remove(uid);
        log.info("客户端{} , 关闭连接",uid);
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("收到消息，UID:{} 内容: {} ",uid,message);
        try {
            //httpSender向chatGPT发起请求,拿到结果
            String result = httpSender.post(message);
            //给客户端返回结果
            sendMessage(result);
        }catch (Exception e){
            e.printStackTrace();
            sendMessage("服务器故障");
        }
    }


    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
        log.error("发生错误，{} ",uid,error.getMessage());
    }

    public void sendMessage(String message)  {
        log.error("发送消息，UID:{} ,内容：{} ",uid,message);
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
